package com.noyes4j;

import com.noyes4j.encrypt.CompositeCrypto;
import com.noyes4j.encrypt.Crypto;
import com.noyes4j.encrypt.CryptoException;
import com.noyes4j.encrypt.KeyGenerator;
import com.noyes4j.encrypt.asymmetric.AsymmetricAlgorithm;
import com.noyes4j.encrypt.asymmetric.RSA;
import com.noyes4j.encrypt.digest.*;
import com.noyes4j.encrypt.symmetric.*;
import com.noyes4j.encrypt.utils.IoUtil;
import com.noyes4j.encrypt.utils.RadixUtil;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyPair;

/**
 * @ClassName test
 * @Description: TODO
 * @Author zhaoweiqin
 * @Date 2021/2/4
 * @Version V1.0
 **/
public class test {


    @Test
    public void testMd5() throws Exception{
        String src = "赵伟钦";
        Assert.assertEquals("1681A7F12EEC0BBAE4F0164A9D12E945",new Md5().encrypt(src));
    }

    @Test
    public void testDes(){
        String src = "赵伟钦";
        Crypto crypto = new DesCrypto("xxssyyyy");
        final String xx = crypto.encrypt(src);
        System.out.println("encrypt=>"+crypto.encrypt(src));
        System.out.println("decrypt=>"+crypto.decrypt(xx));
        Assert.assertEquals("C3CC634B67E858D2E09C14A48C5FC266",xx);
        Assert.assertEquals(src,crypto.decrypt(xx));

        final String yy = crypto.encrypt(src,"UTF-8");
        Assert.assertEquals("C3CC634B67E858D2E09C14A48C5FC266",yy);
        Assert.assertEquals(src,crypto.decrypt(yy));

    }
    @Test
    public void testBase64() throws Exception{
        String src = "赵伟钦";
        Crypto crypto = new Base64Crypto();
        final String xx = crypto.encrypt(src).trim();
        System.out.println("encrypt=>"+xx);
        Assert.assertEquals("6LW15Lyf6ZKm",xx);
        Assert.assertEquals(src,crypto.decrypt(xx));

        String yy = Base64.encode(src);

        Assert.assertEquals("6LW15Lyf6ZKm",yy);
        Assert.assertEquals(src,crypto.decrypt(yy));
        Assert.assertEquals(src, Base64.decodeStr(yy));

        crypto = new Base64OptCrypto(false , true);
        String encrypt = crypto.encrypt(src);
        Assert.assertEquals("6LW15Lyf6ZKm",encrypt);
        Assert.assertEquals(src,crypto.decrypt(encrypt));
    }
    @Test
    public void testUrl() {
        String src = "赵伟钦";
        Crypto crypto = new UrlCrypto();
        final String xx = crypto.encrypt(src);
        System.out.println("encrypt=>"+xx);
        Assert.assertEquals("%E8%B5%B5%E4%BC%9F%E9%92%A6",xx);
        Assert.assertEquals(src,crypto.decrypt(xx));

    }
    @Test
    public void testAes() {
        String src = "赵伟钦";
        Crypto crypto = new AesCrypto("xxssyyyyssxx");
        final String xx = crypto.encrypt(src);
        System.out.println("encrypt=>"+xx);
        Assert.assertEquals("N2qfAtyBVeR5jl4z1mJzCA==",xx);
        Assert.assertEquals(src,crypto.decrypt(xx));

    }
    @Test
    public void testDESAS() {
        String src = "赵伟钦";
        Crypto crypto = new DESAS("xxssyyyy");
        final String xx = crypto.encrypt(src);

        System.out.println("encrypt=>"+xx);

        Assert.assertEquals("4beebbfece7cca30a8415e13b75dc400",xx);
        Assert.assertEquals(src,crypto.decrypt(xx));

    }
    @Test
    public void testComposite() throws Exception{
        String src = "赵伟钦";
        Crypto base64Crypto = new Base64Crypto();
        Crypto desCrypto = new DesCrypto("xxssyyyy");

        CompositeCrypto compositeCrypto = new CompositeCrypto();
        //这个就能很好地表达先进行什么加密再进行什么加密，自动逆序解密
        compositeCrypto.add(base64Crypto).add(desCrypto).add(base64Crypto);

        final String xx = compositeCrypto.encrypt(src);
        System.out.println("encrypt=>"+xx);
        Assert.assertEquals("Qzk5NUE0Q0M5OERCODRFMUVCOTUyNjI3RUQ4RjY2RjM=",xx);
        Assert.assertEquals(src,compositeCrypto.decrypt(xx));

    }

    /**
     * 测试整数的二进制表示
     */
    @Test
    public void testBinary(){
        int a = -6;
        for (int i = 0; i < 32; i++) {
            int t = (a & 0x80000000>>>i)>>>(31-i);
            System.out.print(t);
        }
    }

    @Test
    public void testAesHutool() throws Exception{
        String src = "赵伟钦";
        Crypto crypto = new AES();
        String xx = crypto.encrypt(src);
        System.out.println(xx);//因为key是随机的，所以每次不一样
        Assert.assertEquals(src,crypto.decrypt(xx));

        crypto = new AES(new byte[]{1,2,3,4,5,6,7,8,9,9,9,9,9,9,9,9});
        String yy = crypto.encrypt(src);
        Assert.assertEquals("ABB14FD029E022CF15DD66AB23D35284",yy);
        Assert.assertEquals(src,crypto.decrypt(yy));
    }
    @Test
    public void testDesHutool() throws Exception{
        String src = "赵伟钦";
        Crypto crypto = new DES();
        String xx = crypto.encrypt(src);
        System.out.println(xx);
        Assert.assertEquals(src,crypto.decrypt(xx));

        crypto = new DES(new byte[]{1,2,3,4,5,6,7,8,9,9,9,9,9,9,9,9});
        String yy = crypto.encrypt(src);
        Assert.assertEquals("CAECD1C98967F549FF8D5418498C148A",yy);
        Assert.assertEquals(src,crypto.decrypt(yy));
    }
    @Test
    public void testRsa() throws Exception{
        String src = "赵伟钦";
        //应该是产生之后就保存下来
        KeyPair keyPair = KeyGenerator.generateKeyPair(AsymmetricAlgorithm.RSA.getValue());
        Crypto crypto = new RSA(keyPair.getPrivate(),keyPair.getPublic());
        String encrypt = crypto.encrypt(src);
        System.out.println(encrypt);
        System.out.println(crypto.decrypt(encrypt));
    }
    @Test(expected = CryptoException.class)
    public void testDigester() throws Exception{
        String src = "赵伟钦";
        Crypto crypto = new Digester(DigestAlgorithm.SHA256);
        String xx = crypto.encrypt(src);
        System.out.println(xx);
        Assert.assertEquals("1B15011247E93A0579AB980AB8BFDF13F612AEE2C81B3ADB6A5445804A97CD54",xx);
        System.out.println(crypto.decrypt(xx));
    }
    @Test(expected = CryptoException.class)
    public void testHmac() throws Exception{
        String src = "赵伟钦";
        Crypto crypto = new HMac(HmacAlgorithm.HmacSHA256,new byte[]{1,2,3,4,5,6,7,8});
        String xx = crypto.encrypt(src);
        System.out.println(xx);
        Assert.assertEquals("AE44CF7D3748EB18D3A35B9345CD19CB0A37415A10C836D529E126D5115E8DB8",xx);
        System.out.println(crypto.decrypt(xx));
    }

    @Test
    @Ignore
    public void testStream() throws Exception{
        Crypto crypto = new AES(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16});
        FileInputStream in = new FileInputStream("C:\\Users\\xiongshiyan\\Desktop\\1.txt");//"赵伟钦" -> 1.txt
        FileOutputStream out = new FileOutputStream("C:\\Users\\xiongshiyan\\Desktop\\2.bat");
        crypto.encrypt(in,out);

        String encrypt = crypto.encrypt("赵伟钦");
        Assert.assertEquals("E4B1ED894580A0784BE84812EA68314A",encrypt);
        FileInputStream outin = new FileInputStream("C:\\Users\\xiongshiyan\\Desktop\\2.bat");
        String hex = RadixUtil.toHex(IoUtil.stream2Bytes(outin));
        Assert.assertEquals(encrypt,hex);

        in.close();
        out.close();
        outin.close();
    }

    /**
     * 测试整数的二进制表示
     */
    @Test
    public void testHex() throws Exception{
        byte[] bytes = "赵伟钦".getBytes("UTF-8");
        System.out.println(RadixUtil.toHex(bytes));
        System.out.println(RadixUtil.toHexLower(bytes));
        Assert.assertEquals("E8B5B5E4BC9FE992A6" , RadixUtil.toHex(bytes));
        Assert.assertEquals("e8b5b5e4bc9fe992a6" , RadixUtil.toHexLower(bytes));
    }

}
